import { Injectable, Inject } from '@angular/core';
import { Task, TaskList } from '../domain/index';
import { Observable } from 'rxjs/Observable';
import { HttpClient, HttpHeaders } from '@angular/common/http';

@Injectable()
export class TaskService {

  // 定义api路径
  private readonly domain = 'tasks';
  private headers = new HttpHeaders({ 'Content-Type': 'application/json' });
  constructor(
    @Inject('BASE_CONFIG') private config,
    private http: HttpClient) { }

  /**
   * 添加项目
   * @param task
   */
  add(task: Task): Observable<Task> {
    task.id = null;
    const uri = `${this.config.uri}/${this.domain}`;
    return this.http
      .post<Task>(uri, JSON.stringify(task), { headers: this.headers });
  }
  /**
   * 修改项目
   * @param task
   */
  update(task: Task): Observable<Task> {
    const uri = `${this.config.uri}/${this.domain}/${task.id}`;
    const toUpdate = {
      desc: task.desc,
      priority: task.priority,
      dueDate: task.dueDate,
      reminder: task.reminder,
      ownerId: task.ownerId,
      participantIds: task.participantIds,
      remark: task.remark
    };
    return this.http
      // 指定修改的选项
      .patch<Task>(uri, JSON.stringify(toUpdate), { headers: this.headers });
  }

  /**
   * 删除项目
   * @param task
   */
  del(task: Task): Observable<Task> {
    const uri = `${this.config.uri}/taskLists/${task.id}`;
    return this.http.delete(uri).mapTo(task);
  }

  get(taskListId: string): Observable<Array<Task>> {
    const uri = `${this.config.uri}/${this.domain}`;
    return this.http
      .get<Array<Task>>(uri, { params: { 'taskListId': taskListId } });
  }

  /**
   * 获取所有的task
   * @param lists
   */
  getByLists(lists: TaskList[]): Observable<Task[]> {
    return Observable.from(lists)
      .mergeMap(list => this.get(list.id))
      .reduce((tasks: Task[], t: Task[]) => [...tasks, ...t], []);
  }

  complete(task: Task): Observable<Task> {
    const uri = `${this.config.uri}/taskLists/${task.id}`;
    return this.http.patch<Task>(uri,
      JSON.stringify({ completed: !task.completed }),
      { headers: this.headers });
  }

  /**
   * 移动
   * @param taskId
   * @param tasktListId
   */
  move(taskId: string, tasktListId: string): Observable<Task> {
    const uri = `${this.config.uri}/${this.domain}/${taskId}`;
    return this.http
      .patch<Task>(uri, JSON.stringify({ tasktListId: tasktListId }), { headers: this.headers });
  }

  moveAll(srcListId: string, targetListId: string): Observable<Task[]> {
    return this.get(srcListId)
      .mergeMap(tasks => Observable.from(tasks))
      .mergeMap(task => this.move(task.id, targetListId))
      .reduce((arr, x) => [...arr, x], []);
  }
}
